package org.example.mall.admin.util;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.example.mall.admin.configuration.exception.BaseException;
import org.example.mall.admin.configuration.exception.IStatus;
import org.example.mall.admin.configuration.exception.Status;

import java.io.Serializable;

/**
 * @author hzq
 * @date 2021/10/12 16:51
 */
@Data
public class R<T> implements Serializable {

    /**
     * 状态码
     */
    private Integer code;

    /**
     * 消息提示
     */
    private String message;

    /**
     * 返回数据
     */
    private T data;

    public R() {

    }

    /**
     * 全参构造函数
     *
     * @param code    状态码
     * @param message 消息提示
     * @param data    返回数据
     */
    public R(Integer code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * 构造一个自定义的API返回
     *
     * @param code    状态码
     * @param message 消息提示
     * @param data    返回数据
     * @return ApiResponse
     */
    public static <T> R<T> of(Integer code, String message, T data) {
        return new R<>(code, message, data);
    }

    /**
     * 构造一个成功且不带返回数据的API
     *
     * @return ApiResponse
     */
    public static R ofSuccess() {
        return ofSuccess(null);
    }

    /**
     * 构造一个成功且带返回数据的API
     *
     * @param data 返回数据
     * @return ApiResponse
     */
    public static <T> R<T> ofSuccess(T data) {
        return ofStatus(Status.SUCCESS, data);
    }

    /**
     * 构造一个成功且返回自定义消息的API
     *
     * @param message 消息提示
     * @return ApiResponse
     */
    public static R ofSuccessMessage(String message) {
        return of(Status.SUCCESS.getCode(), message, null);
    }

    /**
     * 构造一个成功且带消息提示/返回数据的API
     *
     * @param message 消息提示
     * @param data    返回数据
     * @return ApiResponse
     */
    public static <T> R<T> ofSuccess(String message, T data) {
        return of(Status.SUCCESS.getCode(), message, data);
    }

    /**
     * 构造一个失败且不带返回数据的API
     *
     * @return ApiResponse
     */
    public static R ofError() {
        return ofStatus(Status.ERROR, null);
    }


    public static <T> R<T> ofError(T data) {
        return ofStatus(Status.ERROR, data);
    }

    /**
     * 构造一个失败且不带返回数据的API
     *
     * @return ApiResponse
     */
    public static <T> R<T> ofError(String message, T data) {
        return of(Status.ERROR.getCode(), message, data);
    }

    /**
     * 构造一个失败且返回自定义消息的API
     *
     * @param message 消息提示
     * @return ApiResponse
     */
    public static R ofErrorMessage(String message) {
        return of(Status.ERROR.getCode(), message, null);
    }

    /**
     * 构造一个远程调用失败且不带返回数据的API
     *
     * @return ApiResponse
     */
    public static R ofFeignError() {
        return ofStatus(Status.FEIGN_ERROR, null);
    }

    /**
     * 构造一个远程调用失败且不带返回数据的API
     *
     * @param cause 异常原因
     * @return ApiResponse
     */
    public static <T> R ofFeignError(T cause) {
        return ofStatus(Status.FEIGN_ERROR, cause);
    }

    /**
     * 构造一个有状态的API返回
     *
     * @param status 状态 {@link Status}
     * @return ApiResponse
     */
    public static R ofStatus(Status status) {
        return ofStatus(status, null);
    }

    /**
     * 构造一个有状态且带返回数据的API
     *
     * @param status 状态 {@link IStatus}
     * @param data   返回数据
     * @return ApiResponse
     */
    public static <T> R<T> ofStatus(IStatus status, T data) {
        return of(status.getCode(), status.getMessage(), data);
    }

    /**
     * 构造一个返回异常的API
     *
     * @param e   异常
     * @param <E> {@link BaseException} 的子类
     * @return ApiResponse
     */
    public static <E extends BaseException> R ofException(E e) {
        return of(e.getCode(), e.getMessage(), e.getData());
    }

    /**
     * 是否成功
     *
     * @return true 成功 / false 失败
     */
    @JsonIgnore
    public boolean isSuccess() {
        return Status.SUCCESS.getCode().equals(this.getCode());
    }

    /**
     * 是否失败
     *
     * @return true 失败 / false 成功
     */
    @JsonIgnore
    public boolean isError() {
        return !this.isSuccess();
    }

    /**
     * 是空数据
     *
     * @return true 空数据 / false 非空数据
     */
    @JsonIgnore
    public boolean isNullData() {
        return null == this.getData();
    }

    /**
     * 是非空数据
     *
     * @return true 非空数据 / false 空数据
     */
    @JsonIgnore
    public boolean isNotNullData() {
        return !this.isNullData();
    }

    /**
     * 失败 或 空数据
     */
    @JsonIgnore
    public boolean isErrorOrIsNullData() {
        return (this.isError() || this.isNullData());
    }
}
